/*
ID: icerupt1
PROG: prefix
LANG: C++11
*/

/*
 * using a trie-tree to store all primitives' reverse string, 
 * and then iterate S with O(len(S) * maxlen(primitive)) to determine
 * if length i is a possible prefix.
*/
#include <fstream>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>

std::ifstream fin {"prefix.in" };
std::ofstream fout{"prefix.out"};

struct trie_node
{
	char value;
	bool mark;
	std::vector<trie_node*> children;

	trie_node()
	{
		children.resize(26);
	}
};

struct trie
{
	trie_node* root;
	int count;
};

std::vector<std::string> primitive;
std::string sequence;

trie_node* trie_crate_node()
{
	trie_node* pnode = new trie_node;
	pnode->mark = false;
	(pnode->children).resize(26);
	return pnode;
}

void trie_init(trie* ptrie)
{
	ptrie->root = trie_crate_node();
}

void trie_insert(trie* ptrie, std::string s)
{
	auto pnode = ptrie->root;
	for (auto it = s.begin(); it != s.end(); ++it) {
		int index = (*it) - 'A';
		if (!(pnode->children[index])) pnode->children[index] = trie_crate_node();
		pnode = pnode->children[index];
		pnode->value = *it;
		if (std::next(it) == std::end(s)) pnode->mark = true;
	}
}

int main()
{
	trie trie_tree;
	trie_init(&trie_tree);
	for (std::string tmp; fin >> tmp && tmp != "."; ) {
		primitive.push_back(tmp);
		std::reverse(tmp.begin(), tmp.end());
		trie_insert(&trie_tree, tmp);
	}
	for (std::string tmp; fin >> tmp; ) sequence += tmp;

	bool f[sequence.size() + 1];
	std::fill(f, f + sequence.size() + 1, false);

	f[0] = true;
	for (int i = 1; i <= (int)sequence.size(); i++) {
		trie_node* pnode = trie_tree.root;
		for (int j = i-1; j >= 0; j--) {
			if (!(pnode->children[sequence[j] - 'A'])) break;
			pnode = pnode->children[sequence[j] - 'A'];
			if (pnode->mark) f[i] |= f[j];
		}
	}

	int len = sequence.size();
	for (; len >= 0; len--) if (f[len]) break;
	std::cout << len << '\n';
	fout << len << '\n';
}
